package com.example.stringbufferlogger.controller;


import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.stringbufferlogger.Utils.JsonUtils;
import com.example.stringbufferlogger.Utils.OkHttpUtil;
import com.example.stringbufferlogger.dto.CompareDataDTO;
import com.example.stringbufferlogger.dto.HttpRequest;
import com.example.stringbufferlogger.dto.HttpResponse;
import com.example.stringbufferlogger.dto.ReplayEntryDTO;
import com.example.stringbufferlogger.entity.LogRecord;
import com.example.stringbufferlogger.entity.ReplayLog;
import com.example.stringbufferlogger.entity.ReplayResult;
import com.example.stringbufferlogger.service.DwrRequestProcessor;
import com.example.stringbufferlogger.service.LogRecordService;
import com.example.stringbufferlogger.service.ReplayLogService;
import com.example.stringbufferlogger.service.ReplayResultService;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 流量回放模块
 */
@RestController
@RequestMapping("/api/replayLog")
@Slf4j
public class ReplayLogController {

    @Resource
    private ReplayLogService replayLogService;
    @Resource
    private LogRecordService logRecordService;
    @Resource
    private DwrRequestProcessor dwrRequestProcessor;
    @Resource
    private ReplayResultService replayResultService;


    /**
     * 接收日志数据并保存到数据库
     *
     * @param replayEntryDTO 日志数据
     * @return 处理结果
     */
    @PostMapping("/save")
    public ResponseEntity<String> receiveLog(@org.springframework.web.bind.annotation.RequestBody ReplayEntryDTO replayEntryDTO) {

        LogRecord record = logRecordService.getLogRecordByRequestId(replayEntryDTO.getRequestId());
        if (record == null) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("未找到请求内容");
        }
        try {
            HttpResponse response = replayRequest(record.getRequestId());

            // 创建一个新的ReplayLog对象，并将DTO中的属性复制到该对象
            ReplayLog replayLog = new ReplayLog();
            BeanUtils.copyProperties(record, replayLog);
            // 设置回放结果信息
            replayLog.setResponseBody(response.getBody());
            replayLog.setStatus(response.getStatus());
            replayLog.setContentType(getContentTypeFromHeaders(response.getHeaders()));

            // 设置时间戳
            replayLog.setTimeStamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));
            replayLog.setCreateTime(new Date());
            replayLog.setCompareStatus("0");
            replayLog.setReplayStatus("0");

            // 保存日志到数据库
            replayLogService.save(replayLog);
            return ResponseEntity.ok("日志接收成功");
        } catch (Exception e) {
            System.out.println("处理日志异常" + e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("服务器错误");
        }
    }


    /**
     * 单个请求回放
     */
    public HttpResponse replayRequest(String requestId) {
        LogRecord record = logRecordService.getLogRecordByRequestId(requestId);

        try {
            // 1. 准备请求
            HttpRequest request = prepareRequest(record);

            // 2. 执行请求
            HttpResponse response = executeRequest(request);

            // 3. 结果比对
            boolean isMatch = compareResponse(record, response);

            // 4. 保存结果
            ReplayResult result = new ReplayResult();
            result.setRequestId(requestId);
            result.setOriginalValue(record.getResponseBody());
            result.setReplayValue(response.getBody());
            if (isMatch == false) {
                result.setDiffFlag("1");
            } else {
                result.setDiffFlag("0");
            }


            replayResultService.save(result);
            return response;

        } catch (Exception e) {
            log.error("请求回放失败: {}", requestId, e);
//            return ReplayResult.failure(requestId, e.getMessage());
            return null;
        }
    }

    /**
     * 准备请求
     */
    private HttpRequest prepareRequest(LogRecord record) {
        // 特殊处理DWR请求
        if (isDwrRequest(record)) {
            return dwrRequestProcessor.prepareDwrRequest(record);
        }

        // 普通HTTP请求处理
        HttpRequest request = new HttpRequest();
        request.setUrl(convertUrl(record.getUrl()));
        request.setMethod(record.getMethod());
        request.setSessionId(record.getSessionId());
        // 解析 HeadersR
        request.setHeaders((Map<String, String>) convertToMap(record.getHeaders()));
        request.setSessionattributes((Map<String, String>) convertToMap(record.getSessionAttributes()));
        Map<String, String> parameters = (Map<String, String>) convertToMap(record.getRequestParams());
        request.setRequestParams(parameters);  // 确保HttpRequest类有parameters字段和setter方法

        // 处理请求体
        if ("POST".equalsIgnoreCase(record.getMethod())) {
            request.setBody(record.getRequestBody());
        }


        return request;
    }

    /**
     * 执行请求
     */
    private HttpResponse executeRequest(HttpRequest request) throws IOException {
//        // 构建OkHttp请求
//        Request.Builder builder = new Request.Builder()
//                .url(request.getUrl());
//
//        // 添加session cookie
//        if (request.getSessionId() != null) {
//            builder.addHeader("Cookie", "JSESSIONID=" + request.getSessionId());
//        }
//
//        // 添加Session属性作为自定义header（Base64编码）
//        if (request.getSessionattributes() != null && !request.getSessionattributes().isEmpty()) {
//            String sessionAttributesJson = JsonUtils.toJson(request.getSessionattributes());
//            String encodedSession = Base64.getEncoder().encodeToString(sessionAttributesJson.getBytes(StandardCharsets.UTF_8));
//            builder.addHeader("X-Replay-Session", encodedSession);
//        }
//
//        // 设置请求方法
//        String method = request.getMethod().toUpperCase();
//        RequestBody body = method.equals("GET") || method.equals("HEAD")
//                ? null
//                : RequestBody.create(MediaType.parse("text/plain"), request.getBody());
//
//        switch (method) {
//            case "GET":
//                builder.get();
//                break;
//            case "POST":
//                builder.post(body);
//                break;
//            case "PUT":
//                builder.put(body);
//                break;
//            case "DELETE":
//                builder.delete(body);
//                break;
//            case "PATCH":
//                builder.patch(body);
//                break;
//            default:
//                throw new IllegalArgumentException("Unsupported HTTP method: " + method);
//        }
//
//        // 设置原始请求头
//        if (request.getHeaders() != null) {
//            request.getHeaders().forEach(builder::addHeader);
//        }
//
//        // 执行请求
//        try (Response response = OkHttpUtil.execute(builder.build())) {
//            HttpResponse httpResponse = new HttpResponse();
//            httpResponse.setStatus(response.code());
//
//            // 转换响应头
//            Headers headers = response.headers();
//            Map<String, String> responseHeaders = new HashMap<>();
//            for (String name : headers.names()) {
//                responseHeaders.put(name, headers.get(name));
//            }
//
//            // 获取响应体
//            ResponseBody responseBody = response.body();
//            httpResponse.setBody(responseBody != null ? responseBody.string() : "");
//
//            return httpResponse;
//        }

        // 1. 构建包含所有信息的请求体
        // 1. 构建包含所有信息的请求体
        Map<String, Object> requestPayload = new HashMap<>();
        requestPayload.put("originalRequest", new HashMap<String, Object>() {{
            put("method", request.getMethod());
            put("headers", request.getHeaders());
            put("body", request.getBody());
            put("parameter", request.getRequestParams());  // 添加parameters
        }});
        requestPayload.put("sessionData", new HashMap<String, Object>() {{
            put("sessionId", request.getSessionId());
            put("sessionAttributes", request.getSessionattributes());
        }});

        // 2. 创建JSON请求体
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(
                mediaType,
                JsonUtils.toJson(requestPayload)
        );

        // 3. 直接使用原始URL构建请求
        Request.Builder builder = new Request.Builder()
                .url(request.getUrl())  // 使用原始URL
                .post(body)  // 统一使用POST方法传输
                .addHeader("Content-Type", "application/json")
                .addHeader("X-Replay-Request", "true")  // 标记这是回放请求
                .addHeader("X-Original-Method", request.getMethod());  // 记录原始HTTP方法

        // 4. 执行请求
        try (Response response = OkHttpUtil.execute(builder.build())) {
            HttpResponse httpResponse = new HttpResponse();
            httpResponse.setStatus(response.code());

            // 转换响应头
            Headers headers = response.headers();
            Map<String, String> responseHeaders = new HashMap<>();
            for (String name : headers.names()) {
                responseHeaders.put(name, headers.get(name));
            }
            httpResponse.setHeaders(responseHeaders);

            // 获取响应体
            ResponseBody responseBody = response.body();
            httpResponse.setBody(responseBody != null ? responseBody.string() : "");
            System.out.println("请求返回：" + httpResponse);

            return httpResponse;
        }
    }

    /**
     * 响应比对
     */
    private boolean compareResponse(LogRecord record, HttpResponse response) {
        if (record.getStatus() != response.getStatus()) {
            return false;
        }

        // 简单实现 - 实际可能需要更复杂的比对逻辑
        return StringUtils.equals(record.getResponseBody(), response.getBody());
    }

    /**
     * URL转换（老系统URL转新系统URL）
     */
    private String convertUrl(String oldUrl) {
        // 实现URL映射逻辑，可以从配置或数据库读取
        return oldUrl.replace(oldUrl, "http://127.0.0.1:8080/ADMQRY0001/queryCustInfo");
    }

    /**
     * 判断是否是DWR请求
     */
    private boolean isDwrRequest(LogRecord record) {
        return record.getPath() != null && record.getPath().contains("/dwr/");
    }

    private Map<String, ? extends String> convertToMap(String input) {
        if (input == null || input.isEmpty()) {
            return new HashMap<>();
        }
        try {
            // 尝试按JSON解析
            return JsonUtils.parseMap(input, String.class, String.class);
        } catch (Exception e1) {
            try {
                // 尝试按键值对解析
//                return parseKeyValueString(input, ",", ":");
            } catch (Exception e2) {
                log.error("Failed to parse input: {}", input, e2);
                return new HashMap<>();
            }
        }
        return null;
    }

    private String getContentTypeFromHeaders(Map<String, String> headers) {
        if (headers == null) {
            return null;
        }
        return headers.entrySet().stream()
                .filter(e -> "Content-Type".equalsIgnoreCase(e.getKey()))
                .map(Map.Entry::getValue)
                .findFirst()
                .orElse(null);
    }

    /**
     * 数据对比
     */
    @PostMapping("/compare")
    public ResponseEntity<String> replayResult(CompareDataDTO replayResultDTO) {
        return replayResultService.replayResult(replayResultDTO);
    }

}